Skip to main content

Forms custom validation

כשעושים ולידציה לשדה בטופס מקבלים קוד שאומר האם הולידציה עברה או נכשלה. הקוד הזה נמצא בתוך fieldName.errors.

כל ולידציה היא פונקציה שמקבלת control: AbstractControl ומחזירה ValidationErrors | null.

נניח שאנחנו רוצים לעשות ולידציה לשם משתמש כך שהוא מחרוזת ללא רווחים.

בתוך הקומפוננטה נשים את הפונקציה של הולידציה.

comp.ts
noSpaceAllowed(control: FormControl){
const value = control.value;

if(value != null && value.indexOf(' ') != -1){
return {noSpaceAllowed: true}
}
return null;
}

בהגדרת שדות הטופס, נחבר את פונקצית הולידציה.

comp.ts
firstName: ['', [Validators.required, this.noSpaceAllowed]],

get firstName() {
return this.contactForm.get('presonalDetails.firstName');
}

בטמפלט נשתמש בשדה שהגדרנו ונבדוק את הערך שהפונקציה החזירה על מנת לאתר שגיאות.

comp.html
<span *ngIf="firstName?.errors?.['noSpaceAllowed']">First name is required</span>

Async validator

אנחנו צריכים Async validator כששולחים http request. ולידטור אסינכרוני מחזיר promise או observable.

נניח שאנחנו רוצים לקבל מיילים רק עם סיומת מסויימת ויש לנו ב-DB רשימה של מיילים מותרים.

נגדיר את הפונקציה של הולידציה בתוך קובץ ה-class.

comp.ts
emailNotAllowed(control: FormControl): Promise<any> | Observable<any> {
const response = new Promise((resolve, reject) => {
// Timer to assimulate async action
setTimeout(() => {
if (control.value !== 'service@taxes.gov.il') {
resolve({ emailNotAllowed: true });
} else {
resolve(null);
}
}, 5000);
});
return response;
}

הקריאה לולידטור תהיה ברשימה נפרדת מזו של הולידטורים הרגילים.

comp.ts
email: ['', [Validators.required, Validators.email], this.emailNotAllowed]

Value & status change events

אירוע ValueChange יקרה אם יהיה שינוי בערך של FormCOntrol, FormGroup או FormArray. אנחנו נרשמים לקבל את השינויים בפונקציה OnInit.

comp.ts
this.contactForm.get('message')?.valueChanges.subscribe(value => {
console.log(value);
})

אפשר גם להאזין לשינויים שיש ב-form עצמו.

comp.ts
this.contactForm.valueChanges.subscribe(value => {
console.log(value);
})

לכל form control יש סטטוס. אם שדה אחד הוא invalid, כל הטופס יהיה invalid. כשיש בדיקה של ולידציה, האירוע StatusChanges עולה.

אפשר לחבר את הערכים שמקבלים למשתנים ב-class ולהשתמש בהם.

comp.ts
this.contactForm.statusChanges.subscribe(value => {
console.log(value);
})

Setting values to the form

אפשר לחבר ערכים לשדות של הטופס. המבנה של הפונקציה חייב להתאים למבנה של הטופס.

comp.ts
this.contactForm = this.formBuilder.group({
presonalDetails: this.formBuilder.group({
firstName: ['', [Validators.required, this.noSpaceAllowed]],
lastName: '',
email: ['', [Validators.required, Validators.email], this.emailNotAllowed,],
}),
message: '',
subjects: new FormArray([new FormControl(null)]),
});

שימוש בפונקציה setValue:

comp.ts
this.contactForm.setValue({
presonalDetails: {
firstName: '',
lastName: '',
email: ''
},
message: '',
subjects: []
})

שימוש בפונקציה patchValue להשמה חלקית של הערכים:

comp.ts
this.contactForm.patchValue({
personalDetails: {
firstName: ''
}
})

אפשר לאפס טופס:

comp.ts
this.contactForm.reset({
presonalDetails: {
firstName: '',
lastName: '',
email: ''
},
message: 'Write your message',
subjects: []
})